package com.zf.nospring.rabbitmq.direct;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.zf.nospring.rabbitmq.utils.RabbitUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * Direct交换机。
 * 路由模式使用 Direct交换机
 * 向该类型交换机发送消息时，如果 消息携带的路由键和绑定时配置的路由键 字符完全匹配，就把消息发送给对应的绑定队列中。
 * <p>
 * 某条消息从交换机发送到队列时，就算某个队列在该交换机上多次绑定且多次满足路由条件也只会往该队列中发送一条该消息
 */
public class DirectProducer {
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = RabbitUtils.getDefaultConnection();
        Channel channel = connection.createChannel();
        // 声明交换机
       /*
           exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
           参数：
              exchange:交换机名称
              type:交换机类型
              durable:是否持久化
              autoDelete:自动删除
              internal：如果 true 表示该交换机只能 rabbitmq 内部使用的交换机，我们的客户端无法直接使用，所以一般false，默认是false
              arguments：参数
        */
        String exchangeName = "test_direct";
        //声明交换机，不存在就创建，存在就校验已经存在的参数和声明的参数是否一致，不一致就报错
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null);
        //声明队列，不存在就创建，存在就校验已经存在的参数和声明的参数是否一致，不一致就报错
        String queue1Name = "test_direct_queue1";
        String queue2Name = "test_direct_queue2";

        channel.queueDeclare(queue1Name, true, false, false, null);
        channel.queueDeclare(queue2Name, true, false, false, null);
        //绑定队列和交换机，指定路由键，如果已存在的绑定的队列、交换机、路由键、参数完全一致则不再重复绑定，否则就创建绑定
        //绑定 test_direct_queue1 队列 到交换机 并 指定路由键：error
        channel.queueBind(queue1Name, exchangeName, "error");
        //绑定 test_direct_queue2 队列 到交换机 并 指定路由键：info  error  warning
        channel.queueBind(queue2Name, exchangeName, "error");
        channel.queueBind(queue2Name, exchangeName, "warning");

        // 发送消息，指定路由键 为 warning，会被发送到 test_direct_queue2 队列
        channel.basicPublish(exchangeName, "warning", null, "ier".getBytes());
        // 发消息，指定路由键 error, 会被发送到 test_direct_queue1 和 test_direct_queue2 队列
        channel.basicPublish(exchangeName, "error", null, "error".getBytes());

        channel.close();
        connection.close();

    }
}
